package cn.itcalvin.sncoal.cth.exception;

import cn.hutool.json.JSONException;
import cn.itcalvin.vo.Message;
import cn.itcalvin.vo.MessageUtil;
import cn.itcalvin.vo.ResultStatus;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author calvin
 */
@Slf4j
@RestControllerAdvice
@Order(99999999)
public class GlobalExceptionHandler {

    /**
     * 一般的参数绑定时候抛出的异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public Message handleBindException(BindException ex){
        log.error(   "参数校验异常",ex);
        List<String> defaultMsg = ex.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        return MessageUtil.error(String.join(",", defaultMsg));
    }
    /**
     * 一般的参数绑定时候抛出的异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public Message handleArgumentNotValidException(MethodArgumentNotValidException ex){
        log.error(   "参数校验异常",ex);
        List<String> defaultMsg = ex.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        return MessageUtil.error(String.join(",", defaultMsg));
    }


    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Message exceptionHandler(Exception ex){
        log.error("异常",ex);
        return MessageUtil.error(ex.getMessage());
    }

    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    @ResponseBody
    public Message exceptionHandler(HttpMessageNotReadableException ex){
        log.error(   "服务错误异常",ex);
        return MessageUtil.error("服务错误异常！");
    }





    @ExceptionHandler(value = JSONException.class)
    @ResponseBody
    public  Message jSONException(JSONException ex){
        log.error("json转化失败:\r"+ex.getCause(),ex);
        return MessageUtil.error("数据转化处理失败！");
    }

    /**
     * sql执行异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = SQLException.class)
    @ResponseBody
    public  Message sqlException(SQLException ex){
        log.error("数据服务调用异常！",ex);
        return MessageUtil.error("数据服务调用异常，请稍后重试！");
    }

    /**
     * 数据效验异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = InvalidFormatException.class)
    @ResponseBody
    public  Message invalidException(InvalidFormatException ex){
        log.error("存在数据格式错误！",ex);
        return MessageUtil.error("存在数据格式错误！");
    }

    /**
     * 数据效验异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    @ResponseBody
    public  Message maxUploadSizeExceededException(MaxUploadSizeExceededException ex){
        log.error("上传文件过大！",ex);
        return MessageUtil.error("上传文件过大！");
    }
    /**
     * 数据效验异常
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MissingServletRequestPartException.class)
    @ResponseBody
    public  Message missingServletRequestPartException(MissingServletRequestPartException ex){
        log.error("上传参数异常",ex);
        return MessageUtil.error("上传参数异常！"+ex.getMessage());
    }


    /**
     * 登录校验
     * @param ex
     * @return
     */
    @ExceptionHandler(value = AuthException.class)
    @ResponseBody
    public  Message authException(AuthException ex){
//        log.error("请登录后重试！",ex);
        return MessageUtil.error(ResultStatus.TOKEN_ERROR);
    }

    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public  Message businessException(BusinessException ex){
//        log.error("自定义异常:"+ex.getMsg(),ex);
        return MessageUtil.error(ex.getMessage());
    }


}
